import pandas as pd

def calculate_technical_indicators(df):
    # 计算RSI(14)
    delta = df['close'].diff()
    gain = delta.where(delta > 0, 0)
    loss = -delta.where(delta < 0, 0)
    avg_gain = gain.rolling(14).mean()
    avg_loss = loss.rolling(14).mean()
    rs = avg_gain / avg_loss
    df['rsi'] = 100 - (100 / (1 + rs))

    # 计算MACD
    ema12 = df['close'].ewm(span=12, adjust=False).mean()
    ema26 = df['close'].ewm(span=26, adjust=False).mean()
    df['macd'] = ema12 - ema26
    df['signal'] = df['macd'].ewm(span=9, adjust=False).mean()
    df['histogram'] = df['macd'] - df['signal']
    
    # 计算CCI(20)
    tp = (df['high'] + df['low'] + df['close']) / 3
    cci_mean = tp.rolling(20).mean()
    mad = tp.rolling(20).apply(lambda x: abs(x - x.mean()).mean())
    df['cci'] = (tp - cci_mean) / (0.015 * mad)
    
    # 计算BOLL(20)
    ma20 = df['close'].rolling(20).mean()
    std20 = df['close'].rolling(20).std()
    df['boll_upper'] = ma20 + 2 * std20
    df['boll_mid'] = ma20
    df['boll_lower'] = ma20 - 2 * std20
    
    # 计算DMI(14)
    # 真实波幅TR
    tr = pd.DataFrame({
        'hl': df['high'] - df['low'],
        'hc': abs(df['high'] - df['close'].shift()),
        'lc': abs(df['low'] - df['close'].shift())
    }).max(axis=1)
    
    # 方向移动DM
    up = df['high'] - df['high'].shift()
    down = df['low'].shift() - df['low']
    dm_plus = np.where((up > down) & (up > 0), up, 0)
    dm_minus = np.where((down > up) & (down > 0), down, 0)
    
    # 平滑处理
    dm_plus_smooth = pd.Series(dm_plus).rolling(14).mean()
    dm_minus_smooth = pd.Series(dm_minus).rolling(14).mean()
    tr_smooth = tr.rolling(14).mean()
    
    # 计算+DI和-DI
    df['plus_di'] = (dm_plus_smooth / tr_smooth) * 100
    df['minus_di'] = (dm_minus_smooth / tr_smooth) * 100
    df['adx'] = (abs(df['plus_di'] - df['minus_di']) / (df['plus_di'] + df['minus_di'])) * 100
    
    # 计算KDJ(9,3,3)
    low_min = df['low'].rolling(9).min()
    high_max = df['high'].rolling(9).max()
    rsv = (df['close'] - low_min) / (high_max - low_min) * 100
    df['k'] = rsv.ewm(com=2).mean()
    df['d'] = df['k'].ewm(com=2).mean()
    df['j'] = 3 * df['k'] - 2 * df['d']
    
    # 计算OBV
    obv = (np.where(df['close'] > df['close'].shift(), df['vol'], 
                   np.where(df['close'] < df['close'].shift(), -df['vol'], 0))).cumsum()
    df['obv'] = obv
    
    # 计算SAR（抛物线指标）
    ep = df['high'].iloc[0]
    sar = [df['low'].iloc[0]]
    af = 0.02
    for i in range(1, len(df)):
        sar_next = sar[i-1] + af * (ep - sar[i-1])
        if df['high'].iloc[i] > ep:
            ep = df['high'].iloc[i]
            af = min(af + 0.02, 0.2)
        if sar_next > df['low'].iloc[i]:
            sar_next = df['low'].iloc[i]
            af = 0.02
            ep = df['high'].iloc[i]
        sar.append(sar_next)
    df['sar'] = sar
    
    # 计算WR(14)
    high14 = df['high'].rolling(14).max()
    low14 = df['low'].rolling(14).min()
    df['wr'] = (high14 - df['close']) / (high14 - low14) * -100
    
    # 计算MA系列
    df['ma5'] = df['close'].rolling(5).mean()
    df['ma10'] = df['close'].rolling(10).mean()
    df['ma20'] = df['close'].rolling(20).mean()
    df['ma40'] = df['close'].rolling(40).mean()
    df['ma60'] = df['close'].rolling(60).mean()
    df['ma120'] = df['close'].rolling(120).mean()
    
    # 计算SKDJ(9,3)
    df['sk'] = df['k'].rolling(3).mean()
    df['sd'] = df['sk'].rolling(3).mean()

    # 计算ABI（涨跌指标）
    df['abi'] = (df['advance'] - df['decline']).abs() / (df['advance'] + df['decline']) * 100

    # 计算ADL（累积派发线）
    mfm = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low'])
    mfm = mfm.replace([np.inf, -np.inf], 0).fillna(0)
    df['adl'] = (mfm * df['vol']).cumsum()

    # 计算ADR（涨跌比率）
    df['adr'] = df['advance'].rolling(10).sum() / df['decline'].rolling(10).sum()

    # 计算ARMS指标（TRIN）
    adv_dec_ratio = df['advance'] / df['decline']
    arms = (adv_dec_ratio.rolling(10).mean() / adv_dec_ratio.rolling(5).mean()) * 100
    df['arms'] = arms.replace([np.inf, -np.inf], 100)
    
    # 计算BTI（广量冲力指标）
    df['bti'] = (df['advance'] - df['decline']) / (df['advance'] + df['decline']) * df['vol']

    # 计算MCL（麦克连指标）
    ema1 = df['close'].ewm(span=3).mean()
    ema2 = df['close'].ewm(span=6).mean()
    df['mcl'] = ema1 - ema2

    # 计算MSI（麦氏综合指标）
    df['msi'] = (df['close'].rolling(10).mean() + df['vol'].rolling(5).mean()) / 2

    # 计算OBOS（超买超卖指标）
    obos = df['advance'].rolling(10).sum() - df['decline'].rolling(10).sum()
    df['obos'] = obos / df['vol'].rolling(10).mean()

    # 计算STIX（短期交易指数）
    stix_ema = df['close'].ewm(span=6).mean()
    df['stix'] = (df['close'] - stix_ema) / stix_ema * 100

    # 计算CHO（佳庆指标）
    ad_line = df['adl'].diff().rolling(10).sum()
    df['cho'] = ad_line / df['vol'].rolling(10).mean()

    # 计算CYE（趋势指标）
    cye_ma1 = df['close'].rolling(5).mean()
    cye_ma2 = df['close'].rolling(20).mean()
    df['cye'] = (cye_ma1 - cye_ma2) / cye_ma2 * 100

    # 计算DMA（平行线差指标）
    dma_short = df['close'].rolling(10).mean()
    dma_long = df['close'].rolling(50).mean()
    df['dma'] = dma_short - dma_long

    # 计算DPO（区间震荡线指标）
    dpo_period = 20
    dma = df['close'].rolling(dpo_period).mean()
    df['dpo'] = df['close'].shift(dpo_period//2) - dma

    # 计算EMV（简易波动指标）
    dm = ((df['high'] + df['low'])/2 - (df['high'].shift() + df['low'].shift())/2)
    br = df['vol'] / (df['high'] - df['low'])
    df['emv'] = dm / br.replace(0, 1).rolling(14).mean()

    # 计算JS（杰斯通道）
    js_high = df['high'].rolling(20).max()
    js_low = df['low'].rolling(20).min()
    df['js_upper'] = js_high - (js_high - js_low)*0.1
    df['js_lower'] = js_low + (js_high - js_low)*0.1
    
    return df.dropna()